/**
 * 
 */
package org.wmine.data;

import java.io.File;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.StringTokenizer;


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**1
 * @author Rajeev
 *This class is to initialise appropriate objects of classes Table , attribute, and Tuple 
 *after we parse xml file to preserve there values
 *   
 */
public class XMLDataReader extends AbstractDataReader {
	private DocumentBuilder parser;
	private Document xmlDocument;
	private ArrayList<Attribute> attributeCollection;
	private ArrayList<Tuple> tupleCollection;
	Table sampleTable = new Table();;
 	//private ArrayList<String> singleTupleCollection;
	String xmlFilePath;
	
	public XMLDataReader(StringBufferInputStream xmlFilePath) throws ParserConfigurationException, SAXException, IOException {
		//this.xmlFilePath = xmlFilePath; 
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder parser = factory.newDocumentBuilder();
		xmlDocument = (Document) parser.parse(xmlFilePath);
		attributeCollection = new ArrayList<Attribute>(); // to store attributes as collection
		tupleCollection = new ArrayList<Tuple>(); // to store tuples as collection
		parseXML();
	}
	
	private void parseXML() {
		NodeList tableList= xmlDocument.getElementsByTagName("table");
		int noOfTables = tableList.getLength();
		
		
		for (int i = 0 ; i < noOfTables ; i++){
			Element element = (Element) tableList.item(i);
			sampleTable.setNameTable(getElementFromXmlFile(element, "tablename"));
					
			NodeList attributeList = xmlDocument.getElementsByTagName("attribute");
			int noOfAttributes = attributeList.getLength();
			sampleTable.setNoOfAttributes(noOfAttributes); // setting no of attributes in Table class
				//System.out.println("Attributes are : "+sampleTable.getNoOfAttributes());
			for (int j = 0; j < noOfAttributes; j++) {
				Element elementA =  (Element) attributeList.item(j);
				Attribute singleAttribute = new Attribute();
				/*
				 *The below code initialises attributes in Attribute class
				 *  
				 */

				singleAttribute.setAttributeName(getElementFromXmlFile(elementA,"name"));
				singleAttribute.setAttributeType(getElementFromXmlFile(elementA,"type"));
				//System.out.println(singleAttribute.getAttributeName());
				//System.out.println(singleAttribute.getAttributeType());
				attributeCollection.add(singleAttribute);	//below code adds name and types of attribute 			
			}
			/*
			 * Table class  member is a collection of Attribute
			 * below we set attributelist of the Table sampleTable
			 */
			sampleTable.setAttributeList(attributeCollection);
			
			/*
			 * Extracting tuples from the xml doc
			 */
			NodeList tupleList = xmlDocument.getElementsByTagName("tuple");
			int noOfTuples = tupleList.getLength();
			sampleTable.setNoOfTuples(noOfTuples);
			//System.out.println("no of tuples : "+sampleTable.getNoOfTuples());
			for (int j = 0; j < noOfTuples; j++) {
				Element elementTuple = (Element) tupleList.item(j);
				Tuple singleTuple = new Tuple();
				ArrayList<String> singleTupleCollection = new ArrayList<String>(); // to store single tuples string values as collection
			
				/*
				 * extracting child nodes of tuple tag directly below and adding them to 
				 * a arraylist of strings
				 */
				String childs = elementTuple.getChildNodes().item(0).getNodeValue().toString();
				//System.out.println(childs);
				StringTokenizer tupleValues= new StringTokenizer(childs,",");
			
				while (tupleValues.hasMoreElements()) {
					String temp = tupleValues.nextToken();
					//System.out.println("added field "+temp);
					singleTupleCollection.add(temp);					 
				}
				//System.out.println("added tuple ");
				
				// initialising array of strings of a single tuple of tuple class 
				singleTuple.setTupleValuesList(singleTupleCollection);
				tupleCollection.add(singleTuple);	 
			}
				sampleTable.setTupleList(tupleCollection);	
				/*
				 * The below code is to extract values of the tuples from the classes Table ,
				 * Tuple and Attribute				   
				 */
			/*	ArrayList<Tuple> testTupleCollection = new ArrayList<Tuple>(); 
				testTupleCollection= sampleTable.getTupleList();
				int noOfTuples1 = sampleTable.getNoOfTuples();	
				//System.out.println(noOfTuples1);
				
				for (int k = 0; k<noOfTuples1 ;k++) {
					Tuple tempTuple = testTupleCollection.get(k);
					
					ArrayList<String> stringTuple = tempTuple.getTupleValuesList();
					//System.out.println("no of fields "+stringTuple.size());
					for (int j = 0; j < stringTuple.size(); j++) {
						System.out.println(stringTuple.get(j));	
					}
					
				}						*/
							 
		}	
}
	
	public String getElementFromXmlFile(Element elementA, String tagName){
		NodeList temp = (NodeList) elementA.getElementsByTagName(tagName);
		Element subElement = (Element) temp.item(0);
			return subElement.getFirstChild().getNodeValue();
	}
		 		
	 
	
	@Override
	public Table getTable() {
		return sampleTable ;
	}
}
